[Hadoop] 分布式文件系统HDFS 二

HDFS环境搭建、常见问题(小文件问题、Namenode内存管理、数据迁移、数据平衡)、数据压缩、纠删码

Posted by 李玉坤 on 2017-05-31

HDFS环境搭建

官网安装文档
Hadoop伪分布式安装步骤
http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html

下载Hadoop
http://archive.cloudera.com/cdh5/cdh/5/
2.6.0-cdh5.7.0
或则 wget http://archive.cloudera.com/cdh5/cdh/5/hadoop-2.6.0-cdh5.7.0.tar.gz

前置条件:记得检查hostname和配置host映射

  1. jdk安装

    1
    2
    3
    4
    5
    6
    解压:tar -zxvf jdk-7u79-linux-x64.tar.gz -C ~/app
    添加到系统环境变量: ~/.bash_profile
    export JAVA_HOME=/home/hadoop/app/jdk1.7.0_79
    export PATH=\$JAVA_HOME/bin:$PATH
    使得环境变量生效: source ~/.bash_profile
    验证java是否配置成功: java -v
  2. 安装ssh

    1
    2
    3
    sudo yum install ssh
    ssh-keygen -t rsa
    cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
  3. 下载并解压hadoop

    1
    2
    下载:直接去cdh网站下载
    解压:tar -zxvf hadoop-2.6.0-cdh5.7.0.tar.gz -C ~/app
  4. hadoop配置文件的修改(hadoop_home/etc/hadoop)
    hadoop-env.sh

    1
    2
    3
    4
    5
    export JAVA_HOME=/home/hadoop/app/jdk1.7.0_79

    # mkdir /home/hadoop/tmp
    # chmod -R 777 /home/hadoop/tmp
    export HADOOP_PID_DIR=/home/hadoop/tmp

core-site.xml

1
2
3
4
5
6
7
8
9
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop000:8020</value>
</property>

<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/app/tmp</value>
</property>

hdfs-site.xml

1
2
3
4
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
  1. 启动hdfs
    格式化文件系统(仅第一次执行即可,不要重复执行):hdfs/hadoop namenode -format
    启动hdfs: sbin/start-dfs.sh
    验证是否启动成功:

    jps

     DataNode

     SecondaryNameNode
     NameNode
    浏览器访问方式 http://hadoop000:50070

  2. 停止hdfs
    sbin/stop-dfs.sh

HDFS关键设置及常见问题

常用配置

1
2
3
4
配置文件路径:$HADOOP_HOME$/etc/hadoop
主要配置文件:
•hdfs-site.xml
•core-site.xml

常见问题

小文件问题

  • 定义:大量大小小于块大小的文件
  • 实际场景:网页,Hive动态分区插入数据等
  • 背景:每个文件的元数据对象约占150byte,所以如果有1千万个小文件,每个文件占用一个block,则NameNode大约需要2G空间。如果存储1亿个文件,则NameNode需要20G空间;数据以块为单位进行处理。
  • 影响:占用资源,降低处理效率
  • 解决方案:
    • 从源头减少小文件
    • 使用archive打包
    • 使用其他存储方式,如Hbase、ES存储网页类型文件,使用spark等给hive分区数据重新合并切割。

Namenode内存管理

大数据量下的namenode问题:

  1. 启动时间变长
  2. 性能开始下降
  3. NameNode JVM FGC风险较高

解决方案:

  1. 根据数据增长情况,预估namenode内存需求,提前做好预案
  2. 使用HDFS Federation,扩展NameNode分散单点负载
  3. 引入外部系统支持NameNode内存数据
  4. 合并小文件(有相关的命令:hadoop archive)
  5. 调整合适的BlockSize

内存结构

内存预估
文件元数据对象约占200byte,block元数据约占180byte:
总内存 =198 * num(Directory + Files) + 176 * num(blocks) + 2% * 总内存

数据迁移

场景:

  • 冷热数据迁移
  • 集群升级、维护

方案:

  • hadoop distcp 命令

数据平衡

原因:长期运行的集群增删节点,节点增删磁盘等

影响:

  • 跨节点拷贝数据
  • task会存在任务失败的风险
  • 磁盘利用不均

方案:

  • 集群节点间:hdfs balancer 命令
  • 单节点磁盘间:hdfs diskbalancer 命令

hdfs balancer

参数:

  • -threshold 30 :判断集群是否平衡的目标参数,每一个 datanode
    存储使用率和集群总存储使用率的差值的绝对值都应该小于这个阀
    值

  • dfs.datanode.balance.bandwidthPerSec 30m 传输的时候带宽30M

  • crontab job 每天凌晨20分调度
    [hadoop@hadoop001 sbin]$ ./start-balancer.sh -threshold 5

  • 一个DN节点的多个磁盘的数据均衡
    https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSDiskbalancer.html
    1、dfs.disk.balancer.enabled must be set to true in hdfs-site.xml.
    2、hdfs diskbalancer -plan 执行计划 生成xxx.plan.json
    3、hdfs diskbalancer -execute 执行计划.plan.json 执行
    4、hdfs diskbalancer -query 执行计划 查询状态

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    整体空间占用:30%
    threshold: 10
    balance之后每个dn的空间占用:20-40%

    dn1:60% ;dn2:10%;dn3:30%
    整体:
    dn1:40% ;dn2:30%;dn3:30%

    什么时候手动或调度执行?
    a.新盘加入
    b.监控服务器的磁盘剩余空间 小于阈值 10%,发邮件预警 手动执行
    配置多磁盘参数 dfs.datanode.data.dir /data01,/data02,/data03,/data04 comma-delimited(逗号)
  • -include :执行balance的DN列表

  • dfs.balance.balance.bandwidthPerSec 300MB :balance工具在运行中所能占用的带宽,设置的过大会影响其他任务

建议:

  • 对于一些大型的HDFS集群(随时可能扩容或下架服务器),balance脚本建议作为后台常驻进程
  • 根据官方建议,脚本需要部署在相对空闲的服务器上
  • 停止脚本通过kill进程实现

其他管理命令

  • hdfs dfsadmin
  • hdfs fsck

如何提高数据存取效率

数据压缩-作用

  • 节省数据占用的磁盘空间
  • 加快数据在磁盘和网络中的传输速度,从而提高系统的处理速度

数据压缩-评价指标

  • 压缩比:压缩比越高,压缩后文件越小,所以压缩比越高越好
  • 压缩时间:越快越好
  • 已经压缩的格式文件是否可以再分割:可以分割的格式允许单一文件由多个Mapper程序处理,可以更好的并行化

数据压缩-类型

压缩格式 工具 算法 扩展名 codec类 多文件 splitable native hadoop自带 Hadoop编解码
deflate 无 deflate .deflate DeflateCodec 否 否 是 是 org.apache.hadoop.io.compress.DeflateCodec
gzip gzip deflate .gz GzipCodec 否 否 是 是 org.apache.hadoop.io.compress.GzipCodec
bzip2 bzip2 bzip2 .bz2 Bzip2Codec 是 是 否 是 org.apache.hadoop.io.compress.Bzip2Codec
lzo lzop lzo .lzo LzopCodec 否 是[ifIndex] 否 否 com.hadoop.compression.lzo.LzoCodec
lz4 无 lz4 .lz4 Lz4Codec 否 否 是 否 org.apache.hadoop.io.compress.Lz4Codec
Snappy 无 Snappy .snappy SnappyCodec 否 否 是 否 org.apache.hadoop.io.compress.SnappyCodec

数据压缩-使用场景?

  • HDFS命令行写入:将数据压缩后写入
  • Flume写入:写入时指定hdfs.codeC参数
  • Sqoop写入:写入时指定参数
  • -compression-codec org.apache.hadoop.io.compress.SnappyCodec
  • HBase 数据存储: 创建表时指定
    create ‘xx_table’, {NAME => ‘xx_cf’, COMPRESSION => ‘GZ’}
  • Mapreduce中间结果和最终结果:hadoop jar xxx “-Dmapred.compress.map.output=true”
    “-Dmapred.map.output.compression.codec=xxx”
    “-Dmapred.output.compress=true” “-Dmapred.output.compression.codec=xxx”
  • Hive中间结果和最终结果:
    set hive.exec.compress.intermediate=true
    set mapred.map.output.compression.codec=xxx
    set mapred.map.output.compression.codec=xxx
    set hive.exec.compress.output=true
    set mapred.output.compression.codec=xxx
  • Spark(RDD分区、广播变量、shuffle输出):
    • rdd:spark.rdd.compress,是否压缩已序列化的rdd,默认关闭
    • broadcast:spark.broadcast.compress,是否压缩broadcast数据,默认打开
    • 结果存储:saveAsTextFile(path,codec)
    • 压缩算法:spark.io.compression.codec,默认为snappy

使用建议

  • 选择何种压缩格式:
    • 考虑是否支持切分
    • 压缩率vs压缩速度
  • 什么时候使用:
    • 存储:磁盘空间紧张
    • 计算:性能调优(内存空间占用,IO传输)

纠删码(hadoop3.0之后的功能)

复制策略:1tb的数据需要3tb的磁盘空间。
纠删码:只需要复制策略50%的磁盘空间,而且同样可以保存数据的可靠性。

原理解释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
X1=1
X2=2
X3=3
X1+X2+X3=6
X1+2*X2+3*X3=14
X1+3*X2+4*X3=14

我们需要求出X1,X2,X3的值,那么我们最少需要的方程是? 3
如果有四个方程,允许其中丢失任意一个方程

X1=1
X2=2
X3=3
视为我们的数据

X1+X2+X3=6
X1+2*X2+3*X3=14
X1+3*X2+4*X3=14
视为一个校验/冗余数据

如果是复制策略:要允许任意2份数据丢失,我们需要:3*3=9份数据。恢复的时候只需要找到相同的block直接复制就可以。
如果是纠删码策略:要允许任意2份数据丢失,我们需要:3+2=5份数据,时间换空间的策略。恢复的时候需要的时间大;因为各个block都要参与进来。

一个文件有n个块,最少需要的数据块数是多少?n+2;
不是针对一个文件所有的block块进行纠删码的计算,而是按照一定的size切分成block group,按照block group来计算冗余块。(平衡减少时间)

相关命令

1
2
3
4
5
6
7
8
9
10
11
hdfs ec [COMMAND]
[-listPolicies]
[-addPolicies -policyFile <file>]
[-getPolicy -path <path>]
[-removePolicy -policy <policy>]
[-setPolicy -path <path> [-policy <policy>] [-replicate]]
[-unsetPolicy -path <path>]
[-listCodecs]
[-enablePolicy -policy <policy>]
[-disablePolicy -policy <policy>]
[-help <command-name>]

使用建议

将冷门数据以纠删码格式转存,减少空间占用:

  1. 指定某个目录为纠删码模式:
    hdfs ec -setPolicy -path [path] -policy [policy]
  2. 通过distcp命令将原有数据转存

异构存储

  1. 配置dn存储路径时指定存储格式:
    [SSD]file:///path,[ARCHIVE]file:///path
  2. dn通过心跳汇报自身数据存储目录的StorageType给nn
  3. nn汇总并更新集群内各个节点的存储类型情况
  4. 客户端写入时根据设定的存储策略向nn请求响应的dn作为候
    选节点

相关命令

1
2
3
4
5
6
7
• hdfs storagepolicies [COMMAND]
[-listPolicies]
[-setStoragePolicy -path <path> -policy <policy>]
[-getStoragePolicy -path <path>]
[-unsetStoragePolicy -path <path>]
[-help <command-name>]
• hdfs mover [-p <files/dirs> | -f <local file>]

使用建议

  • 一般使用默认策略(HOT,磁盘)即可
  • ARCHIVE:计算能力较弱,存储密度高,存储冷数据
  • SSD:土豪专用